package me.exchange.com.modules.system.service.impl;

import me.exchange.com.modules.system.domain.Dict;
import me.exchange.com.modules.system.domain.User;
import me.exchange.com.modules.system.dto.DictDto;
import me.exchange.com.modules.system.dto.DictQueryCriteria;
import me.exchange.com.modules.system.mapper.DictMapper;
import me.exchange.com.modules.system.repository.DictRepository;
import me.exchange.com.modules.system.repository.UserRepository;
import me.exchange.com.modules.system.service.DictService;
import me.exchange.com.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.*;

/**
* @author 张玉丰
* @date 2020-04-11
*/
@Service
@CacheConfig(cacheNames = "dict")
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class DictServiceImpl implements DictService {

    @Autowired
    private DictRepository dictRepository;
    @Autowired
    private DictMapper dictMapper;
    @Autowired
    private UserRepository userRepository;

    @Override
    @Cacheable
    public Map<String,Object> queryAll(DictQueryCriteria criteria, Pageable pageable){
        Page<Dict> page = dictRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(dictMapper::toDto));
    }

    @Override
    @Cacheable
    public List<DictDto> queryAll(DictQueryCriteria criteria){
        Sort sort = criteria.getSort();
        return dictMapper.toDto(dictRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),sort));
    }

    @Override
    @Cacheable(key = "#p0")
    public DictDto findById(Long id) {
        Dict dict = dictRepository.findById(id).orElseGet(Dict::new);
        ValidationUtil.isNull(dict.getId(),"Dict","id",id);
        return dictMapper.toDto(dict);
    }
    @Override
    @Cacheable
    public DictDto findByDataKey(String filedKey,String dataKey) {
        Dict dict = dictRepository.findByDataKey(filedKey,dataKey);
        ValidationUtil.isNull(filedKey,"Dict","filedKey",filedKey);
        ValidationUtil.isNull(dataKey,"Dict","dataKey",dataKey);
        return dictMapper.toDto(dict);
    }

    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public DictDto create(Dict resources) {
        User user=userRepository.findByUsername(SecurityUtils.getUsername());
        resources.setCAdminId(user.getId());
        resources.setCAdminTime(new Timestamp(System.currentTimeMillis()));
        resources.setIsdel(true);
        return dictMapper.toDto(dictRepository.save(resources));
    }

    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void update(Dict resources) {
        User user=userRepository.findByUsername(SecurityUtils.getUsername());
        Dict dict = dictRepository.findById(resources.getId()).orElseGet(Dict::new);
        ValidationUtil.isNull( dict.getId(),"Dict","id",resources.getId());
        dict.copy(resources);
        //resources =(Dict)BeanUtil.merge(resources,dict);
        dict.setUAdminId(user.getId());
        dict.setUAdminTime(new Timestamp(System.currentTimeMillis()));
        dictRepository.save(dict);
    }

    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        User user=userRepository.findByUsername(SecurityUtils.getUsername());
        Dict dict = dictRepository.findById(id).orElseGet(Dict::new);
        dict.setIsdel(false);
        dict.setUAdminId(user.getId());
        dict.setUAdminTime(new Timestamp(System.currentTimeMillis()));
        dictRepository.save(dict);
    }
    @Override
    @CacheEvict(allEntries = true)
    @Transactional(rollbackFor = Exception.class)
    public void deleteAll(Set<Long> ids) {
        User user=userRepository.findByUsername(SecurityUtils.getUsername());
        for (Long id : ids) {
            Dict dict = dictRepository.findById(id).orElseGet(Dict::new);
            dict.setIsdel(false);
            dict.setUAdminId(user.getId());
            dict.setUAdminTime(new Timestamp(System.currentTimeMillis()));
            dictRepository.save(dict);
            //dictRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<DictDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (DictDto dict : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("字典名称", dict.getDictionaryName());
            map.put("数据项key", dict.getDataKey());
            map.put("数据项value", dict.getDataVal());
            map.put("描述", dict.getDescribe());
            map.put("备注", dict.getRemark());
            map.put("排序", dict.getSort());
            map.put("创建人", dict.getCAdminId());
            map.put("创建日期", dict.getCAdminTime());
            map.put("修改人", dict.getUAdminId());
            map.put("修改时间", dict.getUAdminTime());
            map.put("是否删除 1未删除 0 删除", dict.getIsdel());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}